#include "factory.h"

int exit_fds[2];
//退出机制信号处理函数
void sig_exit_func(int signum)
{
    write(exit_fds[1],&signum,1);
}

int main(int argc,char** argv)
{
    if(argc!=3)
    {
        printf("/thread_pool_server IP PORT\n");
        return -1;
    }
    pipe(exit_fds);
    if(fork())//父进程用来协助完成退出机制
    {
        close(exit_fds[0]);
        signal(SIGUSR1,sig_exit_func);//将10号信号传给信号处理函数
        wait(NULL);
       return 0;
    }
    close(exit_fds[1]);
    Factory_t f;//主数据结构
    int thread_num=THREAD_NUM;//子线程数量
    int capacity=CAPACITY;//队列容量
    factory_init(&f,thread_num,capacity);//线程池初始化
    factory_start(&f,thread_num);//启动线程池
    int socket_fd;
    tcp_init(&socket_fd,argv[1],argv[2]);
    //接收请求，加锁，放入队列，解锁，signal
    int new_fd;
    struct sockaddr_in client_addr;
    Client_State_t* pnew;
    pQue_t pq=&f.que;//让一个队列指针指向队列
    //epoll注册监控socket_fd,exit_fd[0]
    int epfd=epoll_create(1);
    struct epoll_event evs[2];
    epoll_add(epfd,exit_fds[0]);
    epoll_add(epfd,socket_fd);
    int ready_fd_num,i,j,ret;
    printf("socket_fd=%d\n",socket_fd);
    while(1)
    {
        ready_fd_num=epoll_wait(epfd,evs,2,-1);
        for(i=0;i<ready_fd_num;i++)
        {
            if(evs[i].data.fd==socket_fd)//如果有客户端连接了
            {
                bzero(&client_addr,sizeof(client_addr));//清空
                socklen_t addr_len=sizeof(client_addr);
                new_fd=accept(socket_fd,(struct sockaddr*)&client_addr,&addr_len);
                ERROR_CHECK(new_fd,-1,"accept");
                pnew->new_fd=new_fd;
                if(new_fd!=-1)
                {
                    printf("%d Connect success!\n",new_fd);
                }    
                else
                {
                    printf("%d Connect fail!\n",new_fd);
                    continue;
                }
                bzero(pnew->path,strlen(pnew->path));
                ret=recv(new_fd,pnew->path,strlen(pnew->path),0);//服务器端接收对方发送的数据
                ERROR_CHECK(ret,-1,"recv");
                if(!strncmp("cd",pnew->path,2)||!strncmp("ls",pnew->path,2)||!strncmp("remove",pnew->path,6)||!strncmp("pwd",pnew->path,3))
                {
                    command(pnew);//执行对应函数
                }
                else if(!strncmp("puts",pnew->path,4)||!strncmp("gets",pnew->path,4))//如果是puts或者gets交给子线程
                {
                    pnew=(Client_State_t*)calloc(1,sizeof(Client_State_t));//申请空间
                    //pnew放入队列
                    pnew->new_fd=new_fd;
                    pthread_mutex_lock(&pq->mutex);//加锁
                    que_set(pq,pnew);//放入队列
                    pthread_mutex_unlock(&pq->mutex);//解锁
                    pthread_cond_signal(&f.cond);//使条件成立
                }
                else{
                    continue;
                }
            }
            if(evs[i].data.fd==exit_fds[0])//线程池要退出了
            {
                for(j=0;j<thread_num;j++)//给每一个子线程发送cancel信号
                {
                    pthread_cancel(f.pthid[j]);
                    printf("thread %d cancel success\n",getpid());
                }
                for(j=0;j<thread_num;j++)//等待每一个子线程
                {
                    pthread_join(f.pthid[j],NULL);
                }
            }
        }
    }
    close(socket_fd);//关闭对应的描述符
    close(new_fd);
    return 0;
}
